Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

2 Stron V   1 2 >  
Reply to this topicStart new topic
> Singleton a klasa "statyczna"
menic
post
Post #1





Grupa: Zarejestrowani
Postów: 493
Pomógł: 0
Dołączył: 14.06.2003
Skąd: Tomaszów Lubelski/Rzeszów

Ostrzeżenie: (0%)
-----


Mogłby ktoś wytłumaczyć, jaka jest własciwie róznica pomiędzy wzorcem Singleton a tym, ze w klasie mamy wszystkie metody statyczne? Bo jakoś nie moge dojśc co i kiedy stosowac. Wg mnie to nie ma w tym wiekszej różnicy. A co wy sądzicie?
Go to the top of the page
+Quote Post
Denver
post
Post #2





Grupa: Zarejestrowani
Postów: 132
Pomógł: 0
Dołączył: 24.09.2003
Skąd: Giżycko / Wrocław

Ostrzeżenie: (0%)
-----


Różnica jest, i to bardzo wyraźna.

Singleton to wzorzec projektowy gwarantujący Ci, że nigdy nie stworzysz więcej, niż jeden obiekt danej klasy - zawsze będziesz korzystać z tego samego egzemplarza. Zapewnia Ci to prywatny konstruktor danej klasy. Klasa ta nie musi mieć tylko i wyłącznie statycznych metod.

Klasa zawierająca same metody statyczne natomiast to niejako zbiornik funkcji - np. klasa String udostępniająca statyczne metody String::ToUpperCase czy też String::RemoveFirstFiveLetters. Klasa ta operuje tylko i wyłącznie na podanych jej metodom argumentach, i nie posiada własnych (chyba, że statycznych). No i nigdy nie tworzysz żadnego ezgemplarza tej klasy.
Go to the top of the page
+Quote Post
hwao
post
Post #3


Developer


Grupa: Moderatorzy
Postów: 2 844
Pomógł: 20
Dołączył: 25.11.2003
Skąd: Olkusz




Klasa statyczna posiada statyczne metody, generalnie jest jakby "pojemnikiem" często nie powiązanych ze sobą "funkcji" i przede wszystkim nie posiada instancji ( $obiekt = new Cos() ).

Singleton, posiada zainicjowana klase (obiekt), ba nawet więcej gdyż ten wzorzec jest stosowany wtedy gdy chcemy posiadać tylko jedna instancje danej klasy (tj, wszędzie możemy korzystać tylko z tej klasy, nie istnieje możliwość zainicjowania kolejnej).
Go to the top of the page
+Quote Post
LBO
post
Post #4





Grupa: Zarejestrowani
Postów: 1 415
Pomógł: 117
Dołączył: 7.09.2005
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Dodam do wypowiedzi @hwao, że wzorzec singletona jest bardzo pomocny w dużych projektach. Znika wtedy problem przekazywania obiektów (kiedyś to był problem (kopie, referencje itp) np. Klasa odpowiedzialna za połączenie z bazą - zazwyczaj potrzebna tylko jedna, bo aplikacja operuje na jednej bazie danych.
Go to the top of the page
+Quote Post
menic
post
Post #5





Grupa: Zarejestrowani
Postów: 493
Pomógł: 0
Dołączył: 14.06.2003
Skąd: Tomaszów Lubelski/Rzeszów

Ostrzeżenie: (0%)
-----


Z teoretycznego punktu widzenia rozumiem. Gorzej z praktycznego
Go to the top of the page
+Quote Post
hwao
post
Post #6


Developer


Grupa: Moderatorzy
Postów: 2 844
Pomógł: 20
Dołączył: 25.11.2003
Skąd: Olkusz




Hm patrz (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)

  1. <?php
  2.  
  3. function NewSpace() {
  4. // Jakas nowa przestrzen, tu nie ma zmiennej $Object, z tamtąd
  5. // łapiemy dziada
  6. $Object = Counter::get();
  7.  
  8. echo 'Włączony: '.$Object->getStatus().' razy.'.PHP_EOL;
  9.  
  10. $Object->run();
  11. echo 'Włączony: '.$Object->getStatus().' razy.'.PHP_EOL;
  12.  
  13. }
  14.  
  15. class Counter {
  16. private $i = -1;
  17. private function __construct() {
  18. $this->i = 0;
  19. }
  20.  
  21. private function __clone() {}
  22.  
  23. private static $Instance = null;
  24. public static function get() {
  25. return is_null( self::$Instance ) ? self::$Instance = new Counter() : self::$Instance;
  26. }
  27.  
  28. public function run() {
  29. $this->i++;
  30. }
  31.  
  32. public function getStatus() {
  33. return $this->i;
  34. }
  35. }
  36.  
  37. // Nie darady
  38. //$Object = new Counter();
  39.  
  40. // O, tak lepiej :)
  41. $Object = Counter::get();
  42.  
  43. echo 'Włączony: '.$Object->getStatus().' razy.'.PHP_EOL;
  44.  
  45. $Object->run();
  46. echo 'Włączony: '.$Object->getStatus().' razy.'.PHP_EOL;
  47.  
  48. NewSpace();
  49.  
  50. echo 'Włączony: '.$Object->getStatus().' razy.'.PHP_EOL;
  51.  
  52. ?>

Ciagle operujesz na tym samym obiekcie, nie możesz "powielić".

  1. <?php
  2.  
  3. // Nie darady, prywatny konstrukor
  4. $Object = new Counter();
  5.  
  6. $Object = Counter::get();
  7.  
  8. // Sklonowac dziada tez sie nie da :)
  9. $CloneObject = clone $Object;
  10. ?>


A i rezultat działania (poprawnego).
Kod
Włączony: 0 razy.
Włączony: 1 razy.
Włączony: 1 razy.
Włączony: 2 razy.
Włączony: 2 razy.
Go to the top of the page
+Quote Post
menic
post
Post #7





Grupa: Zarejestrowani
Postów: 493
Pomógł: 0
Dołączył: 14.06.2003
Skąd: Tomaszów Lubelski/Rzeszów

Ostrzeżenie: (0%)
-----


Rozumiem (IMG:http://forum.php.pl/style_emoticons/default/smile.gif) Ale chodzi mi o róznice w zastosowaniu singletona a statycznych metod. Mam klase która działa na wzorcu singleton oraz działa rownie dobrze z metodami statycznymi. Od czego wiec zalezy jaką technike obrać?
Go to the top of the page
+Quote Post
Cysiaczek
post
Post #8





Grupa: Moderatorzy
Postów: 4 465
Pomógł: 137
Dołączył: 26.03.2004
Skąd: Gorzów Wlkp.




Odpowiedź jest niezwykle prosta - od potrzeb : )

Pozdrawiam.
Go to the top of the page
+Quote Post
cadavre
post
Post #9





Grupa: Zarejestrowani
Postów: 472
Pomógł: 7
Dołączył: 7.12.2005
Skąd: Gliwice

Ostrzeżenie: (0%)
-----


Jednak gdy np. połączenia z bazą, w klasie która obsługuje DB nie ma w konstruktorze, a jest ona wywoływana osobną metodą? Wtedy korzystając ze statyków nie nawiązujemy ciągle nowych połączeń.
Go to the top of the page
+Quote Post
Cysiaczek
post
Post #10





Grupa: Moderatorzy
Postów: 4 465
Pomógł: 137
Dołączył: 26.03.2004
Skąd: Gorzów Wlkp.




@cadavre - a singletonem niby tak? Połączenie jest ustawiane raz i potem tylko się do niego odwołujemy, nie ma żadnego kolejnego połączenia. Chyba, że czegoś nie zrozumiałem...

Pozdrawiam.
Go to the top of the page
+Quote Post
cadavre
post
Post #11





Grupa: Zarejestrowani
Postów: 472
Pomógł: 7
Dołączył: 7.12.2005
Skąd: Gliwice

Ostrzeżenie: (0%)
-----


Tak - jak najbardziej jest jak mówisz. Ale porównuję stosowanie statyków i tworzenie nowych instancji bez singletona.
Go to the top of the page
+Quote Post
menic
post
Post #12





Grupa: Zarejestrowani
Postów: 493
Pomógł: 0
Dołączył: 14.06.2003
Skąd: Tomaszów Lubelski/Rzeszów

Ostrzeżenie: (0%)
-----


Czyli tak jak sie domyślałem. Ten singleton to taki lekki pic na wode (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg)
Go to the top of the page
+Quote Post
cadavre
post
Post #13





Grupa: Zarejestrowani
Postów: 472
Pomógł: 7
Dołączył: 7.12.2005
Skąd: Gliwice

Ostrzeżenie: (0%)
-----


Ja też nie widzę sensu w singletonie. Jeśli zdefiniuję sobie:
  1. <?php
  2. $db = new db();
  3. ?>
to dalej w kodzie będę cały czas używał $db a nie tworzył nowe jej instancje, bo po co? A gdy chcę uzyskać dostęp do klasy db w innych klasach to używam już tylko extends'a i komunikuję się z klasą db poprzez Scope Resolution Operator. Naturalnie połączenie z bazą danych uzyskuję na początku głównego pliku, który ładuje wszystkie moduły etc.

EDIT: Gdy potrzebuję przetestować jakąś klasę, która używa np. połączenia z bazą to używam do tego platformy testowej napisanej przeze mnie samego.

Ten post edytował cadavre 25.12.2006, 20:52:21
Go to the top of the page
+Quote Post
y3ti
post
Post #14





Grupa: Zarejestrowani
Postów: 40
Pomógł: 0
Dołączył: 19.08.2004
Skąd: Pruszków

Ostrzeżenie: (0%)
-----


Zgadza się, ale Twój obiekt $db jest zmienną globalną - a przed tym ma właśnie chronić singleton. Powiedzmy, że masz taką sytuację:

  1. <?php
  2. (...)
  3. $db = new DB();
  4.  
  5. class Foo {
  6.  function bar() {
  7.  // $db nie istnieje, musimy korzystać z global
  8.  }
  9. }
  10. ?>


W bar() $db nie istnieje. Musisz wywołać jeszcze raz $db = new DB() - co wiąże się z tym, że będziesz miał dwa takie same obiekty. Możesz również korzystać ze zmiennej globalnej - a fuj nie ładne.

Możesz skorzystać z singletona, który gwarantuje jedną instancje i tylko jedną. Dla przykładu masz klasę Preferences, która przechowuje ustawienia dla całego serwisu. Jeśli klasa X zmieni coś w Preferences to klasa Z musi odczytać tą zmianę (nie mogą być dwa różne obiekty Preferences - może być tylko jeden).

Jednak nadal nie rozumiem, czym się różni funkcjonalnością klasa statyczna od singletona.

Klasa statyczna również:
- nie zezwala na dwie różne wersje objektów
- można przechowywać składowe (np. identyfikator połączenia z bazą danych) - private static
- zachowana jest hermetyzacja

Poza tym korzystanie ze statycznej klasy jest szybsze (nie trzeba pobierać instancji) tj.

  1. <?php
  2. // zamiast 
  3. $db = DB:getInstance();
  4. $db->query(...);
  5.  
  6. // Możemy napisać po prostu
  7. DB:query(...);
  8. ?>
Go to the top of the page
+Quote Post
cadavre
post
Post #15





Grupa: Zarejestrowani
Postów: 472
Pomógł: 7
Dołączył: 7.12.2005
Skąd: Gliwice

Ostrzeżenie: (0%)
-----


O właśnie y3ti zauważyłem błąd w swoim poście. Klasy, które używają db tą właśnie klasę extendują i wszystkie procedury wykonywane są poprzez Scope Resolution Operator (:(IMG:http://forum.php.pl/style_emoticons/default/smile.gif) . Moje frameworki działają na zasadzie identycznej (o ile się nie mylę) z Zendową - istnieje główna klasa, która jest extendowana przez wszystkie inne - dzięki temu mam dostęp do wszystkich klas.

EDIT:
  1. <?php
  2. (...)
  3. $db = new DB();
  4.  
  5. class Foo {
  6.  function bar() {
  7.  // $db nie istnieje, musimy korzystać z global
  8.  }
  9. }
  10. ?>
Tak samo jeśli pierwszą linijkę zastąpisz przez:
  1. <?php
  2. $db = DB::getInstance();
  3. ?>
bo jak w kolejnej ładowanej klasie uzyskasz dostęp do $db? Również musisz globalować.

Ten post edytował cadavre 25.12.2006, 20:58:47
Go to the top of the page
+Quote Post
y3ti
post
Post #16





Grupa: Zarejestrowani
Postów: 40
Pomógł: 0
Dołączył: 19.08.2004
Skąd: Pruszków

Ostrzeżenie: (0%)
-----


Masz rację, ale dzięki singleton możesz stworzyć tylko i wyłącznie jedną instancję obiektu.

Co do różnic pomiędzy singleton a statyczną klasą tak mi coś jeszcze w głowie zaświtało. Gdy taka klasa DB jest finalna to w sumie nie robi różnicy (dla mnie) czy korzystam ze statycznej wersji DB, czy z singletonu.
Jednak co się stanie jeśli będziemy dziedziczyć z DB?
Go to the top of the page
+Quote Post
cadavre
post
Post #17





Grupa: Zarejestrowani
Postów: 472
Pomógł: 7
Dołączył: 7.12.2005
Skąd: Gliwice

Ostrzeżenie: (0%)
-----


Cytat
php 5 introduces the final keyword, which prevents child classes from overriding a method by prefixing the definition with final. If the class itself is being defined final then it cannot be extended.


Finalnej klasy nie można extendować - wiadomo. A gdy dziedziczysz z db to po prostu nie możesz zastąpić metod z klasy finalnej metodami, utworzonymi w klasie dziedziczącej. Różnicy pomiędzy singletonem a statykiem w tym momencie nie widzę.

EDIT: U mnie db nie jest finalną, a finalnymi są te, które extendują db i nie są przez nic extendowane. Final nie służy do wersjonowania, a raczej do tego by zabezpieczyć klasę przez jej extendowaniem, a tym samym możliwą podmianą metod. Tzn. ja tak stosuję final. (IMG:http://forum.php.pl/style_emoticons/default/tongue.gif)

Ten post edytował cadavre 25.12.2006, 23:02:21
Go to the top of the page
+Quote Post
y3ti
post
Post #18





Grupa: Zarejestrowani
Postów: 40
Pomógł: 0
Dołączył: 19.08.2004
Skąd: Pruszków

Ostrzeżenie: (0%)
-----


brrr zagalopowałem się z tymi klasami finalnymi (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg)

Chodziło mi, że różnica jest chyba jest jak będziemy dziedziczyć z klasy statycznej albo singleton - obie klasy oczywiście niefinalne (IMG:http://forum.php.pl/style_emoticons/default/smile.gif) Chodzi o sposób odwoływania się np. do składowych odziedziczonych po rodzicu.

W sumie różnicy nie widzę w funkcjonalności klasy statycznej a singleton. Mimo to wzorzec singleton wymyśliła mądrzejsza od nas osoba, która na 100% była świadoma istnienia klas statycznych i dla tego singleton musi być lepszym rozwiązaniem - tylko dlaczego? (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg)
Go to the top of the page
+Quote Post
cadavre
post
Post #19





Grupa: Zarejestrowani
Postów: 472
Pomógł: 7
Dołączył: 7.12.2005
Skąd: Gliwice

Ostrzeżenie: (0%)
-----


Swoją drogą final'e stosuje się raczej w końcowych fazach projektów, rzadko kiedy w dev-time. Oczywiście jeśli dany moduł (np. klasa właśnie) jest gotowy przed innymi to jak najbardziej można zastanowić się nad finalem. Z praktyki jednak wiem, że nawet gotowe moduły często ulegają zmianie.

Big thx 4 PHP5ZP. (IMG:http://forum.php.pl/style_emoticons/default/biggrin.gif)
Go to the top of the page
+Quote Post
Denver
post
Post #20





Grupa: Zarejestrowani
Postów: 132
Pomógł: 0
Dołączył: 24.09.2003
Skąd: Giżycko / Wrocław

Ostrzeżenie: (0%)
-----


Wydaje mi się, że siłą rzeczy klasa zawierająca same właściwości i metody statyczne będzie po prostu wolniejsza od jej odpowiednika opartego na wzorcu singleton. Radzę porobić testy wydajnościowe, ale intuicja mi mówi, że Singleton po prostu będzie szybszy.
Go to the top of the page
+Quote Post

2 Stron V   1 2 >
Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 28.08.2025 - 11:16